class String
{
public:
	static	Heap				heap;

private:
	struct StringBuffer 
	{
	private:	// data members
		INT		m_reference_count;
		SIZE_T	m_length;

	public:	// Stuff for using the class
		static	StringBuffer*	Create(INT	min_char_count);
		static	VOID				Delete(StringBuffer*);
		SIZE_T	GetAllocationLength()	{	return String::heap.GetSize(this) - sizeof(StringBuffer);	}
		LPTSTR		GetPtr()						{	return (LPTSTR)(this+1); }
		INT		GetReferenceCount()		{	return m_reference_count;	}
		VOID		AddReference()				{	m_reference_count++;	}
		VOID		RemoveReference()			{	m_reference_count--; 
														if (m_reference_count == 0) {	String::heap.Free(this);}
													}
	};
	StringBuffer*	buffer;

public:
	String();
	String(LPCSTR);					// from an ascii string
	String(LPCWSTR);					//	from a unicode string
	String(const String&);			// from an existing instance of the String class
	String(TCHAR character, SIZE_T count = 1);			//	A repetition of this character SIZE_T times
	String(SIZE_T);					// pre allocate it to be at least this big
	String(LPCSTR, SIZE_T);			// start with an existing AscString, but only use the left SIZE_T bytes
	String(LPCWSTR, SIZE_T);		// start with an existing UniString, but only use the left SIZE_T bytes
	String(const String&, SIZE_T);	// start with an existing UniString, but only use the left SIZE_T bytes
   String(LPCSTR, SIZE_T offset, SIZE_T count);
   String(LPCWSTR, SIZE_T offset, SIZE_T count);

	operator	LPCTSTR() const;
	LPTSTR		GetPointer(); //gives you a pointer that you can modify - dont use this unless you intend to modify it

	const		String& operator=(const String&);
	const		String& operator=(CHAR);
	const		String& operator=(WCHAR);
	const		String& operator=(LPCSTR);
	const		String& operator=(LPCWSTR);
	
	const		String& operator+=(const String&);
	const		String& operator+=(CHAR);
	const		String& operator+=(WCHAR);
	const		String& operator+=(LPCSTR);
	const		String& operator+=(LPCWSTR);

	friend	String operator+(const String&,	const String&);
	friend	String operator+(const String&,	CHAR);
	friend	String operator+(const String&,	WCHAR);
	friend	String operator+(CHAR,				const String&);
	friend	String operator+(WCHAR,			const String&);
	friend	String operator+(const String&,	LPCSTR);
	friend	String operator+(const String&,	LPCWSTR);
	friend	String operator+(LPCSTR,		const String&);
	friend	String operator+(LPCWSTR,	const String&);

	TCHAR	operator[](SIZE_T index) const;
	TCHAR	GetCharAt(SIZE_T index) const;
	VOID		SetCharAt(SIZE_T index, TCHAR new_value);
	INT		GetHashCode();
	
	SIZE_T	GetLength() const;
	BOOL		IsEmpty() const;
	VOID		Clear(); //blanks out the string

	INT		CompareBinary(LPCTSTR) const;
	INT		CompareBinaryNoCase(LPCTSTR) const;
	INT		CompareText(LPCTSTR) const;
	INT		CompareTextNoCase(LPCTSTR) const;
	
	VOID		MakeUpper();
	VOID		MakeLower();
	VOID		Trim();
	String	GetUpper();
	String	GetLower();
	String	GetTrim();


	
/*from java

	public boolean regionMatches(INT toffset, String other,
			INT ooffset, INT len)
		throws NullPointerException;
	public boolean regionMatches(boolean ignoreCase, INT toffset,
			String other, INT ooffset, INT len)
		throws NullPointerException;
	public boolean startsWith(String prefix)
		throws NullPointerException;
	public boolean startsWith(String prefix, INT toffset)
		throws NullPointerException;
	public boolean endsWith(String suffix)
		throws NullPointerException;
	public INT indexOf(INT ch);
	public INT indexOf(INT ch, INT fromIndex);
	public INT indexOf(String str)
		throws NullPointerException;
	public INT indexOf(String str, INT fromIndex)
		throws NullPointerException;
	public INT lastIndexOf(INT ch);
	public INT lastIndexOf(INT ch, INT fromIndex);
	public INT lastIndexOf(String str)
		throws NullPointerException;
	public INT lastIndexOf(String str, INT fromIndex)
		throws NullPointerException;
	public String substring(INT beginIndex);
	public String substring(INT beginIndex, INT endIndex);
	public String concat(String str)
		throws NullPointerException;
	public String replace(CHAR oldChar, CHAR newChar);
	public String toLowerCase();
	public String toUpperCase();
	public String trim();

   ToInt();
	ToFloat();
*/


};


